using ERPBackend.Data;
using ERPBackend.Models;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using System;

namespace ERPBackend.Services
{
    public class PurchaseReceiptService : IPurchaseReceiptService
    {
        private readonly ApplicationDbContext _context;

        public PurchaseReceiptService(ApplicationDbContext context)
        {
            _context = context ?? throw new ArgumentNullException(nameof(context));
        }

        public async Task<IEnumerable<PurchaseReceipt>> GetAllPurchaseReceiptsAsync()
        {
            return await _context.PurchaseReceipts
                .Include(pr => pr.Supplier)
                .Include(pr => pr.Warehouse)
                .Include(pr => pr.PurchaseReceiptItems)
                    .ThenInclude(pri => pri.Material)
                .ToListAsync() ?? Enumerable.Empty<PurchaseReceipt>();
        }

        public async Task<int> GetTotalPurchaseReceiptsAsync()
        {
            return await _context.PurchaseReceipts.CountAsync();
        }

        public async Task<IEnumerable<PurchaseReceipt>> GetPurchaseReceiptsPagedAsync(int page, int pageSize)
        {
            int skip = (page - 1) * pageSize;
            return await _context.PurchaseReceipts
                .Include(pr => pr.Supplier)
                .Include(pr => pr.Warehouse)
                .OrderByDescending(pr => pr.CreatedTime)
                .Skip(skip)
                .Take(pageSize)
                .ToListAsync() ?? Enumerable.Empty<PurchaseReceipt>();
        }

        public async Task<PurchaseReceipt?> GetPurchaseReceiptByIdAsync(int id)
        {
            return await _context.PurchaseReceipts
                .Include(pr => pr.Supplier)
                .Include(pr => pr.Warehouse)
                .Include(pr => pr.PurchaseReceiptItems)
                    .ThenInclude(pri => pri.Material)
                .FirstOrDefaultAsync(pr => pr.Id == id);
        }

        public async Task<PurchaseReceipt?> GetPurchaseReceiptByCodeAsync(string receiptCode)
        {
            return await _context.PurchaseReceipts
                .Include(pr => pr.Supplier)
                .Include(pr => pr.Warehouse)
                .Include(pr => pr.PurchaseReceiptItems)
                    .ThenInclude(pri => pri.Material)
                .FirstOrDefaultAsync(pr => pr.ReceiptCode == receiptCode);
        }

        public async Task<PurchaseReceipt> CreatePurchaseReceiptAsync(PurchaseReceipt purchaseReceipt)
        {
            // 检查到货单编码是否已存在
            var existingReceipt = await _context.PurchaseReceipts
                .FirstOrDefaultAsync(pr => pr.ReceiptCode == purchaseReceipt.ReceiptCode);
            if (existingReceipt != null)
            {
                throw new ArgumentException("到货单编码已存在");
            }

            // 检查采购订单是否存在
            var purchaseOrder = await _context.PurchaseOrders.FindAsync(purchaseReceipt.PurchaseOrderId);
            if (purchaseOrder == null)
            {
                throw new ArgumentException("关联的采购订单不存在");
            }

            // 检查供应商是否存在
            var supplier = await _context.Suppliers.FindAsync(purchaseReceipt.SupplierId);
            if (supplier == null)
            {
                throw new ArgumentException("供应商不存在");
            }

            // 检查仓库是否存在
            var warehouse = await _context.Warehouses.FindAsync(purchaseReceipt.WarehouseId);
            if (warehouse == null)
            {
                throw new ArgumentException("仓库不存在");
            }

            // 设置默认状态为待审核
            purchaseReceipt.Status = 0;
            purchaseReceipt.CreatedTime = DateTime.Now;
            purchaseReceipt.UpdatedTime = DateTime.Now;

            // 计算总数量、合格数量和不合格数量
            if (purchaseReceipt.PurchaseReceiptItems != null && purchaseReceipt.PurchaseReceiptItems.Any())
            {
                purchaseReceipt.TotalQuantity = purchaseReceipt.PurchaseReceiptItems.Sum(pri => pri.ReceiptQuantity);
                purchaseReceipt.QualifiedQuantity = purchaseReceipt.PurchaseReceiptItems.Sum(pri => pri.QualifiedQuantity);
                purchaseReceipt.UnqualifiedQuantity = purchaseReceipt.PurchaseReceiptItems.Sum(pri => pri.UnqualifiedQuantity);
            }
            else
            {
                purchaseReceipt.TotalQuantity = 0;
                purchaseReceipt.QualifiedQuantity = 0;
                purchaseReceipt.UnqualifiedQuantity = 0;
            }

            _context.PurchaseReceipts.Add(purchaseReceipt);
            await _context.SaveChangesAsync();
            return purchaseReceipt;
        }

        public async Task<bool> UpdatePurchaseReceiptAsync(PurchaseReceipt purchaseReceipt)
        {
            // 检查到货单是否存在
            var existingReceipt = await _context.PurchaseReceipts.FindAsync(purchaseReceipt.Id);
            if (existingReceipt == null)
            {
                return false;
            }

            // 检查到货单编码是否已被其他到货单使用
            if (existingReceipt.ReceiptCode != purchaseReceipt.ReceiptCode &&
                await _context.PurchaseReceipts.AnyAsync(pr => pr.ReceiptCode == purchaseReceipt.ReceiptCode))
            {
                throw new ArgumentException("到货单编码已被使用");
            }

            // 检查采购订单是否存在
            if (purchaseReceipt.PurchaseOrderId != existingReceipt.PurchaseOrderId)
            {
                var purchaseOrder = await _context.PurchaseOrders.FindAsync(purchaseReceipt.PurchaseOrderId);
                if (purchaseOrder == null)
                {
                    throw new ArgumentException("关联的采购订单不存在");
                }
            }

            // 检查供应商是否存在
            if (purchaseReceipt.SupplierId != existingReceipt.SupplierId)
            {
                var supplier = await _context.Suppliers.FindAsync(purchaseReceipt.SupplierId);
                if (supplier == null)
                {
                    throw new ArgumentException("供应商不存在");
                }
            }

            // 检查仓库是否存在
            if (purchaseReceipt.WarehouseId != existingReceipt.WarehouseId)
            {
                var warehouse = await _context.Warehouses.FindAsync(purchaseReceipt.WarehouseId);
                if (warehouse == null)
                {
                    throw new ArgumentException("仓库不存在");
                }
            }

            // 更新属性
            existingReceipt.ReceiptCode = purchaseReceipt.ReceiptCode;
            existingReceipt.PurchaseOrderId = purchaseReceipt.PurchaseOrderId;
            existingReceipt.SupplierId = purchaseReceipt.SupplierId;
            existingReceipt.ReceiptDate = purchaseReceipt.ReceiptDate;
            existingReceipt.WarehouseId = purchaseReceipt.WarehouseId;
            existingReceipt.Status = purchaseReceipt.Status;
            existingReceipt.TotalQuantity = purchaseReceipt.TotalQuantity;
            existingReceipt.QualifiedQuantity = purchaseReceipt.QualifiedQuantity;
            existingReceipt.UnqualifiedQuantity = purchaseReceipt.UnqualifiedQuantity;
            existingReceipt.Remark = purchaseReceipt.Remark;
            existingReceipt.UpdatedBy = purchaseReceipt.UpdatedBy;
            existingReceipt.UpdatedTime = DateTime.Now;

            _context.Entry(existingReceipt).State = EntityState.Modified;
            return await _context.SaveChangesAsync() > 0;
        }

        public async Task<bool> DeletePurchaseReceiptAsync(int id)
        {
            var purchaseReceipt = await _context.PurchaseReceipts.FindAsync(id);
            if (purchaseReceipt == null)
            {
                return false;
            }

            // 检查是否有相关的明细
            var hasItems = await _context.PurchaseReceiptItems
                .AnyAsync(pri => pri.PurchaseReceiptId == id);
            if (hasItems)
            {
                // 先删除明细
                var items = await _context.PurchaseReceiptItems
                    .Where(pri => pri.PurchaseReceiptId == id)
                    .ToListAsync();
                _context.PurchaseReceiptItems.RemoveRange(items);
            }

            _context.PurchaseReceipts.Remove(purchaseReceipt);
            return await _context.SaveChangesAsync() > 0;
        }

        public async Task<bool> ChangePurchaseReceiptStatusAsync(int id, byte status)
        {
            var purchaseReceipt = await _context.PurchaseReceipts.FindAsync(id);
            if (purchaseReceipt == null)
            {
                return false;
            }

            purchaseReceipt.Status = status;
            purchaseReceipt.UpdatedTime = DateTime.Now;

            _context.Entry(purchaseReceipt).State = EntityState.Modified;
            return await _context.SaveChangesAsync() > 0;
        }

        public async Task<bool> ApprovePurchaseReceiptAsync(int id, int approverId, string? comments)
        {
            var purchaseReceipt = await _context.PurchaseReceipts.FindAsync(id);
            if (purchaseReceipt == null)
            {
                return false;
            }

            // 检查状态是否为待审核
            if (purchaseReceipt.Status != 0)
            {
                throw new InvalidOperationException("只有待审核的到货单才能进行审核");
            }

            // 更新审核状态
            purchaseReceipt.Status = 1; // 已审核
            purchaseReceipt.ApprovedBy = approverId;
            purchaseReceipt.ApprovedTime = DateTime.Now;
            purchaseReceipt.ApprovalComments = comments;
            purchaseReceipt.UpdatedTime = DateTime.Now;

            // TODO: 审核通过后，更新采购订单的到货状态和库存数量
            // 这里需要根据实际业务逻辑实现库存更新

            _context.Entry(purchaseReceipt).State = EntityState.Modified;
            return await _context.SaveChangesAsync() > 0;
        }
    }
}